# CRUD Create Read Update Delete 指数据库的增查改删内容
# 以class类的方式完成以下代码，面向对象的思想
# 通常CRUD只针对文档，不太允许代码去操作仓库和集合
# 引入MongoClient
from pymongo import MongoClient
# 创建Stu类 ，格式要求 首字母大写
class Stu:
    # 构造函数，类被声明使用时，默认会执行的函数
    # 第一个参数self表示引用这个类，在类里面可以使用所有的内容
    def __init__(self):
        self.client = MongoClient('127.0.0.1',27017)
            # 默认使用test数据库
        self.db = self.client['test']
        # 默认使用stu集合
        self.coll = self.db['stu']
    
    # 自定义函数，类被声明后，可以进行调用
    # 第二个参数是自定义参数，调用时，不需要写入第一个参数
    def getClient(self,name):
        print(self.client,name)

    # 创建集合 集合名称由外部传入 如果集合名字存在怎么办??? try except
    def createColl(self,colletion_name):
        try:
            self.db.create_collection(colletion_name)
        except Exception as err:
            print(f"创建集合出错：{err}")

    # 删除集合，集合名称由外部传入 如果集合名字不存在怎么办??? try except
    def dropColl(self,colletion_name):
        try:
            self.db.drop_collection(coll_name)
        except Exception as e:
            print(f"删除集合出错{e}")
    
    # 查看集合
    def getColl(self):
        return self.db.list_collection_names()

    '''文档的增删改 查分为find查和管道查'''
    def findDocs(self,query):
        return list(self.db.stu.find(query))

    def aggDocs(self,pipeline):
        try:
            return list(self.db.stu.aggregate(pipeline))
        except Exception as e:
            print(f'聚合管道操作出错:{e}')

    # 增加文档
    def insertDoc(self,newdoc):
        try:
            self.db.stu1.insert_one(newdoc)
        except Exception as e:
            print(f"增加单个文档报错:{e}")

    # 同步增加多个文档
    def insertDocs(self,newdocs):
        try:
            self.db.stu1.insert_many(newdocs)
        except Exception as e:
            print(f"增加单个文档报错:{e}")
        
    def updateDocs(self,query,sets,doc):
        # db.集合名称.updateMany(查询条件,{操作符:{修改对象}})
        try:
            self.db.stu1.update_many(query,{sets:doc})
        except Exception as e:
            print(f'更新文档出错:{e}')

    #由于set的使用较高，所以单写一个方法执行set符的更新
    def updateSetDoc(self,query,doc):
        self.updateDocs(query,'$set',doc)
    
    def deleteDocs(self,query):
        # db.集合名称.deleteMany(查询条件)
        try:
            return self.db.stu1.delete_many(query)
        except Exception as e:
            print(f'删除文档出错：{e}')
        

# 主函数，默认的执行点
if __name__ == '__main__':
    stu=Stu()
    # stu.insertDoc({'name':"张三",'age':19})
    #print(stu.findDocs())
    docs=[
       {'name':"李四",'age':21},
       {'name':"王五",'age':31}
    ]
    # stu.insertDocs(docs)
    # print(stu.findDocs())
    # query={'name':"张三"}
    # stu.updateDocs(query,'$inc',{'age':2})
    # print(stu.findDocs())
    # stu.updateDocs(query,'$set',{'age':2})
    # print(stu.findDocs())
    # stu.updateSetDoc(query,{'age':19})
    # print(stu.findDocs())
    # stu.deleteDocs({'name':'张三'})
    res = stu.findDocs({'score':{'$gte':90}})
    # print(res)
    # 输出2班成年的男生姓名和年龄
    pipeline=[
        {
            '$match':{
                'className':"2班",
                'age':{'$gte':18},
                'sex':1
            }
        },{
            '$project':{
                '_id':0,
                "姓名":"$stuName",
                'age':1
            }
        }
    ]
    res = stu.aggDocs(pipeline)
    print(res)